package com.baichuan.zntx.rules;

import com.baichuan.common.core.utils.DateUtils;
import com.baichuan.zntx.domain.Device;
import com.baichuan.zntx.domain.Region;
import com.baichuan.zntx.domain.bo.MessageBo;
import com.baichuan.zntx.domain.vo.MessageVo;
import com.baichuan.zntx.service.IMessageService;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.api.Facts;

import java.util.List;

@Rule(name = "Anti-theft Rule", description = "Triggers when the device is out of the designated work area")
public class AntiTheftRule {
    private Device device;
    private final IMessageService messageService;
    public AntiTheftRule(IMessageService messageService){
        this.messageService = messageService;
    }
    // 定义一个方法，用来计算设备是否超出工作区
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        // 地球半径，单位：米
        final int R = 6371000;
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
            + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
            * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        // 距离，单位：米
        return R * c;
    }

    @Condition
    public boolean isOutOfWorkArea(Facts facts) {
        device = facts.get("device");
        Region region = facts.get("region");
        // 计算设备当前位置与工作区中心点的距离
        double distance = calculateDistance(device.getLatitude(), device.getLongtitude(),
            region.getLatitude(), region.getLongtitude());

        // 如果距离超出工作区的半径，则返回true（表示设备在工作区外）
        return distance > region.getRadius();
    }

    @Action
    public void triggerAntiTheftAlarm() {
        MessageBo messageBo = new MessageBo();
        messageBo.setStatus(-1);
        messageBo.setDeviceId(device.getId());
        messageBo.setType(2);
        List<MessageVo> messageVoList = messageService.queryList(messageBo);
        if(messageVoList==null || messageVoList.isEmpty()){
            messageBo.setContent("防盗报警:" + device.getDeviceId());
            messageBo.setSendTime(DateUtils.getNowDate());
            messageBo.setSendCount(0);
            messageService.insertByBo(messageBo);
        }
    }
}

